#include "StreamType.h"
#include "BaseType.h"

void Pauseint8_t(int8_t *val, char type) {
    #ifdef ReadAndPrintOnly
    int8_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(1);
    SetSize(8);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pauseuint8_t(uint8_t *val, char type) {
    #ifdef ReadAndPrintOnly
    uint8_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(2);
    SetSize(8);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pauseint16_t(int16_t *val, char type) {
    #ifdef ReadAndPrintOnly
    int16_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(1);
    SetSize(16);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pauseuint16_t(uint16_t *val, char type) {
    #ifdef ReadAndPrintOnly
    uint16_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(2);
    SetSize(16);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pauseint32_t(int32_t *val, char type) {
    #ifdef ReadAndPrintOnly
    int32_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(1);
    SetSize(32);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pauseuint32_t(uint32_t *val, char type) {
    #ifdef ReadAndPrintOnly
    uint32_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(2);
    SetSize(32);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pauseint64_t(int64_t *val, char type) {
    #ifdef ReadAndPrintOnly
    int64_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(1);
    SetSize(64);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pauseuint64_t(uint64_t *val, char type) {
    #ifdef ReadAndPrintOnly
    uint64_t valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseNumber(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sign = SetSign(2);
    SetSize(64);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseNumber(ValPtr, type);
    #undef ValPtr
    SetSign(sign);
    SetSize(0);
}

void Pausefloat(float *val, char type) {
    #ifdef ReadAndPrintOnly
    float valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseDecimal(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sort = SetSort(2);
    SetSize(32);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseDecimal(ValPtr, type);
    #undef ValPtr
    SetSort(sort);
    SetSize(0);
}

void Pausedouble(double *val, char type) {
    #ifdef ReadAndPrintOnly
    double valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseDecimal(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    int sort = SetSort(2);
    SetSize(64);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseDecimal(ValPtr, type);
    #undef ValPtr
    SetSort(sort);
    SetSize(0);
}

void PauseEnumFunc0(char *val, char type) {
    #ifdef ReadAndPrintOnly
    char valTmp;
    if (val == NULL)
        val = &valTmp;
    *val = ReadNumber();
    if (type != T_Print) return;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    if (type != T_Print) {
        PauseNumber(val, type);
        return;
    }
    #endif // ReadAndPrintOnly
    switch (*val) {
        case 0: PrintLabelValue("false", T_Print); break;
        case 1: PrintLabelValue("true", T_Print); break;
        default: PrintLabelValue(Number2Str(*val), T_Print); break;
    }
}
void Pausebool(bool *val, char type) {
    #ifdef ReadAndPrintOnly
    bool valTmp;
    if (val == NULL)
        val = &valTmp;
    int oldType = type;
    type = T_Read;
    #else // ifndef ReadAndPrintOnly
    CheckInput(val);
    #endif // ReadAndPrintOnly
    #define ValPtr val
    #ifndef ReadAndPrintOnly
    if (type == T_Print) {
        PauseEnumFunc0(ValPtr, T_Print);
        return;
    }
    #endif // ReadAndPrintOnly
    SetSize(1);
    #ifdef ReadAndPrintOnly
    type = oldType;
    #endif // ReadAndPrintOnly
    PauseEnumFunc0(ValPtr, type);
    #undef ValPtr
    SetSize(0);
}

void PauseString(String *val, char type)
{
    #ifndef ReadAndPrintOnly
    CheckInput(val);

    if (type == T_Read) {
    #endif // ReadAndPrintOnly
        SetAlign(1);
        const char *start = (char*) InOut->buf + InOut->pos;
        int len = 0;
        while (start[len] != '\0') len++;
        InOut->pos += len + 1;

        #ifdef ReadAndPrintOnly
        PrintLabelValue(start, type);
        if (val != NULL) {
            *val = (char*) ST_Alloc(len + 1);
            memcpy(*val, start, len);
            (*val)[len] = '\0';
        }
        #else // ifndef ReadAndPrintOnly
        *val = (char*) ST_Alloc(len + 1);
        memcpy(*val, start, len);
        (*val)[len] = '\0';
        #endif // ReadAndPrintOnly
    #ifndef ReadAndPrintOnly
    } else if (type == T_Write) {
        SetAlign(1);
        char *start = (char*) InOut->buf + InOut->pos;
        int len = 0;
        while ((*val)[len] != '\0') len++;
        memcpy(start, *val, len);
        start[len] = '\0';
        InOut->pos += len + 1;
    } else {
        PrintLabelValue(*val, T_Print);
    }
    #endif // ReadAndPrintOnly
}

